package id.co.shuba.spamobile.task;

import java.util.HashMap;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import id.co.shuba.spamobile.App;
import id.co.shuba.spamobile.Encryptor;
import id.co.shuba.spamobile.Sessions;
import id.co.shuba.spamobile.WSException;
import id.co.shuba.spamobile.data.AreaDB;
import id.co.shuba.spamobile.data.DSARDB;
import id.co.shuba.spamobile.data.DatabaseHandler;
import id.co.shuba.spamobile.data.StandardDB;
import id.co.shuba.spamobile.data.ProspectDB;
import id.co.shuba.spamobile.data.ProspectProgressDB;
import id.co.shuba.spamobile.model.DSARInfo;
import id.co.shuba.spamobile.model.ProspectInfo;
import id.co.shuba.spamobile.model.ProspectProgressInfo;
import id.co.shuba.spamobile.model.UserInfo;
import id.co.shuba.spamobile.services.WebServiceHelper;
import id.co.shuba.spamobile.util.Base64;
import android.app.ProgressDialog;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Path.FillType;
import android.os.AsyncTask;
import android.util.Log;

public class DownloadProspectByDateTask extends BaseProgressTask{
	WebServiceHelper _ws;
	SQLiteDatabase _db;		
	INotify _notify;
	UserInfo _user;
	String _imei;
	String _dateStart;
	String _dateEnd;

	public DownloadProspectByDateTask(WebServiceHelper ws, SQLiteDatabase db,
			INotify notify, UserInfo user, String imei, String dateStart, String dateEnd) {
		_ws = ws;
		_db = db;						
		_notify = notify;
		_user = user;
		_imei = imei;
		_dateStart = dateStart;
		_dateEnd = dateEnd;
	}
	
	@Override
	protected AsyncTaskResult<Void> doInBackground(Object... params) {
		try {						
			Encryptor enc = new Encryptor(
					Encryptor.ENC_AES,
					Encryptor.ENC_AES, App.createCompleteKey(_user.getEncryptionKey()), App.IV);
			String pwd = enc.decryptText(_user.getPassword());	
			
			Map<String, Object> properties = new HashMap<String, Object>();
			properties.put("aoCode", _user.getAoCode());
			properties.put("unitCode", _user.getUnitCode());
			properties.put("startDate", _dateStart);
			properties.put("endDate", _dateEnd);
			properties.put("nip", _user.getNip());
			properties.put("password", pwd);
			properties.put("imei", _imei);
			properties.put("token", _user.getToken());			
						
			publishStatus("Downloading Prospect...");
			String result = _ws.Call("GetProspectByDate", properties).toString();
			publishProgress(10);
						
			publishStatus("Extracting Result...");
			String strJSON = new String(Base64.decode(result, Base64.GZIP)); 			
			publishProgress(20);			
			
			JSONObject res = new JSONObject(strJSON);
			String error = res.getString("error");
			if (error.length() > 0 && !error.equals("null"))
				throw new Exception(error);
				
			JSONArray jsonArray = res.getJSONArray("result");												
								
			publishStatus("Updating...");
			int length = jsonArray.length();						
			for (int i = 0; i < length; i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);				
				ProspectInfo info = new ProspectInfo();
				info.setId(getString(jsonObject, "prospectID").trim());
				info.setProspectNo(getString(jsonObject, "prospectNo"));
				info.setFullName(getString(jsonObject, "fullName"));
				info.setJenisUsaha(getString(jsonObject, "jenisUsaha"));
				info.setRencanaPlafon(jsonObject.getLong("rencanaPlafon"));
				info.setMobilePhone(getString(jsonObject, "mobilePhone"));
				info.setOfficePhone(getString(jsonObject, "officePhone"));
				info.setResidentialPhone(getString(jsonObject, "residentialPhone"));
				info.setKodyaKabBusiness(getString(jsonObject, "kodyaKabBusiness"));
				info.setKecamatanBusiness(getString(jsonObject, "kecamatanBusiness"));
				info.setKelurahanBusiness(getString(jsonObject, "kelurahanBusiness"));
				info.setProspectType(getString(jsonObject, "prospectType"));
				info.setDebtorType(getString(jsonObject, "debtorType"));
				info.setChanneling(getString(jsonObject, "channeling"));
				info.setZipCodeBusiness(getString(jsonObject, "zipCodeBusiness"));
				info.setAddressBusiness(getString(jsonObject, "addressBusiness"));
				info.setEksternal(getString(jsonObject, "eksternal"));
				info.setReferensi(getString(jsonObject, "referensi"));											
				info.setAvgExpense(jsonObject.getLong("avgExpense"));
				info.setDateOfBirth(getString(jsonObject, "dateOfBirth"));
				info.setMaritalStatus(getString(jsonObject, "maritalStatus"));
				info.setSpouseName(getString(jsonObject, "spouseName"));
				info.setJmlTanggungan(jsonObject.getInt("jmlTanggungan"));
				info.setProductCode(getString(jsonObject, "productCode"));
				info.setKtpNo(getString(jsonObject, "ktpNo"));
				info.setKtpName(getString(jsonObject, "ktpName"));	
				info.setKtpAddress(getString(jsonObject, "ktpAddress"));
				info.setEntryBy(getString(jsonObject, "entryBy"));
				info.setEntryDate(getString(jsonObject, "entryDate"));
				info.setUpdateBy(getString(jsonObject, "updateBy"));				
				info.setUpdateDate(getString(jsonObject, "updateDate"));				
				info.setAoCode(getString(jsonObject, "aoCode"));
				info.setUnitCode(getString(jsonObject, "unitCode"));
				info.setIsUpload("0");				
				info.setProgressStatus(getString(jsonObject, "progressStatus"));
				info.setUmDecision(getString(jsonObject, "umDecision"));
				info.setUmDecisionNote(getString(jsonObject, "umDecisionNote"));
				info.setUmDecisionDate(getString(jsonObject, "umDecisionDate"));
				info.setReputasiDebitur(getString(jsonObject, "reputasiDebitur"));
				info.setCoAssigned(getString(jsonObject, "coAssigned"));
				info.setAlternateFor(getString(jsonObject, "alternateFor"));
				info.setNotInterestedReason(getString(jsonObject, "notInterestedReason"));
				info.setGuCloseDeal(getString(jsonObject, "guCloseDeal"));
				info.setIsOfflineEntry(getString(jsonObject, "isOfflineEntry"));
				info.setLoanNumber(getString(jsonObject, "loanNumber"));
				info.setCIFNumber(jsonObject.getInt("CIFNumber"));
				info.setOmzet1(jsonObject.getLong("omzet1"));
				info.setOmzet2(jsonObject.getLong("omzet2"));
				info.setOmzet3(jsonObject.getLong("omzet3"));
				info.setOmzet4(jsonObject.getLong("omzet4"));
				info.setOmzet5(jsonObject.getLong("omzet5"));
				info.setOmzet6(jsonObject.getLong("omzet6"));
				info.setOmzet7(jsonObject.getLong("omzet7"));
				info.setOmzet8(jsonObject.getLong("omzet8"));
				info.setOmzet9(jsonObject.getLong("omzet9"));
				info.setOmzet10(jsonObject.getLong("omzet10"));
				info.setOmzet11(jsonObject.getLong("omzet11"));
				info.setOmzet12(jsonObject.getLong("omzet12"));
				info.setOmzetAverage(jsonObject.getLong("omzetAverage"));	
				info.setSourceCode(jsonObject.getString("sourceCode"));
				info.setIsDeleted(jsonObject.getString("isDeleted"));
				info.setPipelineStartTime(jsonObject.getString("pipelineStartTime"));
				info.setPipelineFinishTime(jsonObject.getString("pipelineFinishTime"));
				info.setProspectStartTime(jsonObject.getString("prospectStartTime"));
				info.setProspectFinishTime(jsonObject.getString("prospectFinishTime"));
				info.setGuFup(jsonObject.getString("guFup"));
				info.setIsPipelineKP(jsonObject.getString("isPipelineKP"));		
				info.setUploadBy(getString(jsonObject, "uploadBy"));				
				info.setUploadDate(getString(jsonObject, "uploadDate"));
				info.setFlagFreeze(jsonObject.getInt("flagFreeze"));
				info.setPlaceOfBirth(jsonObject.getString("placeOfBirth"));		
				info.setNIP(jsonObject.getString("nip"));
				info.setKarakter(jsonObject.getString("karakter"));
				
				ProspectDB.addOrUpdate(_db, info, false);
				
				int progress = (int)(20 + (30f * (((float)i)/length)));
				publishStatus(String.format("Updating Prospect...%d/%d", i, length));
				publishProgress(progress);
			}
									
			
			publishStatus("Downloading Prospect Visit...");
			result = _ws.Call("GetProspectVisitByDate", properties).toString();
			publishProgress(60);
						
			publishStatus("Extracting Result...");
			strJSON = new String(Base64.decode(result, Base64.GZIP)); 			
			publishProgress(70);			
			
			res = new JSONObject(strJSON);
			error = res.getString("error");
			if (error.length() > 0 && !error.equals("null"))
				throw new Exception(error);
				
			jsonArray = res.getJSONArray("result");											
										
			publishStatus("Updating Prospect Visit...");
			length = jsonArray.length();						
			for (int i = 0; i < length; i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);				
				DSARInfo info = new DSARInfo();
				info.setProspectID(getString(jsonObject, "prospectID").trim());
				info.setVisitNo(jsonObject.getInt("visitNo"));
				info.setDateVisitPlan(getString(jsonObject, "dateVisitPlan"));
				info.setDateVisitActual(getString(jsonObject, "dateVisitActual"));				
				info.setJoinFieldWork(getString(jsonObject, "joinFieldWork"));
				info.setObjectiveOfVisit(getString(jsonObject, "objectiveOfVisit"));
				info.setResultOfVisit(getString(jsonObject, "resultOfVisit"));
				info.setRemark(getString(jsonObject, "remark"));				
				info.setEntryBy(getString(jsonObject, "entryBy"));
				info.setEntryDate(getString(jsonObject, "entryDate"));
				info.setUpdateBy(getString(jsonObject, "updateBy"));				
				info.setUpdateDate(getString(jsonObject, "updateDate"));
				info.setUploadBy(getString(jsonObject, "uploadBy"));				
				info.setUploadDate(getString(jsonObject, "uploadDate"));
				info.setIsDeleted(getString(jsonObject, "isDeleted"));
				info.setIsUpload("0");
												
				DSARDB.addOrUpdate(_db, info);
				
				int progress = (int)(70 + (30f * (((float)i)/length)));
				publishStatus(String.format("Updating Prospect Visit...%d/%d", i, length));
				publishProgress(progress);
			}
			
			publishStatus("Downloading Prospect Progress...");
			result = _ws.Call("GetProspectProgressByDate", properties).toString();
			publishProgress(60);
						
			publishStatus("Extracting Result...");
			strJSON = new String(Base64.decode(result, Base64.GZIP)); 			
			publishProgress(70);			
			
			res = new JSONObject(strJSON);
			error = res.getString("error");
			if (error.length() > 0 && !error.equals("null"))
				throw new WSException(error);
				
			jsonArray = res.getJSONArray("result");											
										
			publishStatus("Updating Prospect Progress...");
			length = jsonArray.length();						
			for (int i = 0; i < length; i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);				
				ProspectProgressInfo info = new ProspectProgressInfo();
				info.setProspectID(getString(jsonObject, "prospectID").trim());
				info.setProgressStatus(getString(jsonObject, "progressStatus"));
				info.setEntryBy(getString(jsonObject, "entryBy"));
				info.setEntryDate(getString(jsonObject, "entryDate"));
				info.setUpdateBy(getString(jsonObject, "updateBy"));				
				info.setUpdateDate(getString(jsonObject, "updateDate"));
				info.setUploadBy(getString(jsonObject, "uploadBy"));				
				info.setUploadDate(getString(jsonObject, "uploadDate"));
				info.setIsUpload("0");
												
				ProspectProgressDB.addOrUpdate(_db, info);
				
				int progress = (int)(70 + (30f * (((float)i)/length)));
				publishStatus(String.format("Updating Prospect Progress...%d/%d", i, length));
				publishProgress(progress);
			}
			
			publishProgress(0);
			publishStatus("Done!");
			
			return new AsyncTaskResult<Void>((Void) null);
		} catch (WSException we) {
			publishStatus(we.getMessage());
			publishProgress(0);
			return new AsyncTaskResult<Void>(we);
		} catch (Exception e) {
			Log.e("Download", e.getMessage(), e);
			if (e.getMessage().contains("Unable to resolve") || e.getMessage().contains("failed to connect")) {
				publishStatus("Tidak dapat tersambung ke server");
			} else {
				publishStatus(e.getMessage());
			}
			publishProgress(0);
			return new AsyncTaskResult<Void>(e);
		}		
	}		
	
	private String getString(JSONObject obj, String name) throws JSONException {
		String a = obj.getString(name);
		if (a != null) a = a.trim();
		if ("null".equals(a)) return null;
		return a;
	}
	
	@Override
	public String getTitle() {		
		return "Prospect";
	}
	
	@Override
	protected void onPostExecute(AsyncTaskResult<Void> result) {		
		super.onPostExecute(result);
		
		_notify.notifyFinish(result.getError());
	}
	
	@Override
	protected void onCancelled(AsyncTaskResult<Void> result) {		
		super.onCancelled(result);
		
		Log.d("DownloadProspectByDateTask", "Task cancelled");
	}	
}
